﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;

namespace FlanProject.Combats.Actions
{
    public abstract class CombatAction
    {
        public enum CombatActionStage
        {
            NotStarted,
            Preparing,
            Advancing,
            Executing,
            Returning,
            Finishing,
            Complete
        };

        public CombatActionStage Stage { get; set; }

        public abstract bool IsOffensive { get; }
        public abstract bool IsTargetNeeded { get; }

        public CombatCharacter Character { get; set; }
        public CombatCharacter Target { get; set; }

        public virtual bool IsCharacterValidUser { get { return true; } }

        public CombatAction(CombatCharacter character)
        {
            if (character == null)
                throw new ArgumentNullException("No character selected.");

            Character = character;
            Reset();
        }

        public virtual void Reset()
        {
            Stage = CombatActionStage.NotStarted;
        }

        protected virtual void StartStage()
        {
            switch (Stage)
            {
                case CombatActionStage.Preparing:
                    break;

                case CombatActionStage.Advancing:
                    break;

                case CombatActionStage.Executing:
                    break;

                case CombatActionStage.Returning:
                    break;

                case CombatActionStage.Finishing:
                    break;

                case CombatActionStage.Complete:
                    break;
            }
        }

        protected virtual void UpdateCurrentStage(GameTime gameTime)
        {
            switch (Stage)
            {
                case CombatActionStage.NotStarted:
                    break;

                case CombatActionStage.Preparing:
                    break;

                case CombatActionStage.Advancing:
                    break;

                case CombatActionStage.Executing:
                    break;

                case CombatActionStage.Returning:
                    break;

                case CombatActionStage.Finishing:
                    break;

                case CombatActionStage.Complete:
                    break;
            }
        }

        protected virtual bool IsReadyForNextStage
        {
            get
            {
                switch (Stage)
                {
                    case CombatActionStage.Preparing:
                        break;

                    case CombatActionStage.Advancing:
                        break;

                    case CombatActionStage.Executing:
                        break;

                    case CombatActionStage.Returning:
                        break;

                    case CombatActionStage.Finishing:
                        break;
                }

                return true;
            }
        }

        public virtual void Start()
        {
            Stage = CombatActionStage.Preparing;
            StartStage();
        }

        public virtual void Update(GameTime gameTime)
        {
            // Update the current stage
            UpdateCurrentStage(gameTime);

            // If the action is ready for the next stage, then advance
            if ((Stage != CombatActionStage.NotStarted) && (Stage != CombatActionStage.Complete) && IsReadyForNextStage)
            {
                switch (Stage)
                {
                    case CombatActionStage.Preparing:
                        Stage = CombatActionStage.Advancing;
                        break;

                    case CombatActionStage.Advancing:
                        Stage = CombatActionStage.Executing;
                        break;

                    case CombatActionStage.Executing:
                        Stage = CombatActionStage.Returning;
                        break;

                    case CombatActionStage.Returning:
                        Stage = CombatActionStage.Finishing;
                        break;

                    case CombatActionStage.Finishing:
                        Stage = CombatActionStage.Complete;
                        break;
                }

                StartStage();
            }
        }
    }
}
